Redshiftでストアドプロシージャを使う
データアナリティクス事業本部の荒木です。
案件でRedshiftでのストアドプロシージャを使うことがあり、初めてだったので自分でも試してみようと思ったのでそれについてまとめようと思います。
本題
ストアドプロシージャとは
毎回同じようなSQLクエリを実行する場合などに、一連の処理を1つのプログラムとしてまとめてデータベースに保存したものです。 複数の処理なども1回の処理で実行できるようになるので、ネットワークの負荷やサーバの負荷を減らすことができます。
プロシージャの作成
以下のプロシージャは特に引数などを指定せず、一時テーブルに値を挿入した処理を1つの処理にまとめたものです。
CREATE PROCEDURE test_sp1() AS $$ BEGIN DROP TABLE IF EXISTS tmp_tbl; CREATE TEMP TABLE tmp_tbl(id int); INSERT INTO tmp_tbl values (10001),(10002); END; $$ LANGUAGE plpgsql;
処理の中で引数などを使用したい場合、引数名と引数のデータ型を指定することで処理の実行の際に引数を入力することができます。
CREATE PROCEDURE test_sp2(f1 int, f2 varchar(20)) AS $$ DECLARE min_val int; BEGIN DROP TABLE IF EXISTS tmp_tbl; CREATE TEMP TABLE tmp_tbl(id int); INSERT INTO tmp_tbl values (f1),(10001),(10002); SELECT INTO min_val MIN(id) FROM tmp_tbl; RAISE INFO 'min_val = %, f2 = %', min_val, f2; END; $$ LANGUAGE plpgsql;
また、実行処理のSELECT結果等を出力したい場合、出力引数を指定します。その場合引数には入力(IN)、入力および出力 (INOUT)、出力 (OUT)の出力引数を指定します。(指定がない場合、デフォルトの入力(IN)になります。)
CREATE OR REPLACE PROCEDURE test_sp3(f1 IN int, f2 INOUT varchar(256), out_var OUT varchar(256)) AS $$ DECLARE loop_var int; BEGIN IF f1 is null OR f2 is null THEN RAISE EXCEPTION 'input cannot be null'; END IF; DROP TABLE if exists my_etl; CREATE TEMP TABLE my_etl(a int, b varchar); FOR loop_var IN 1..f1 LOOP insert into my_etl values (loop_var, f2); f2 := f2 || '+' || f2; END LOOP; SELECT INTO out_var count(*) from my_etl; END; $$ LANGUAGE plpgsql;
プロシージャの実行
作成したプロシージャはcall
コマンドで実行することができます。
実行時に引数を必要とする場合は引数を入力して実行します。
CALL test_sp1() CALL test_sp2(10,'test') CALL test_sp3(5,'test')
プロシージャの参照・削除
作成したプロシージャを参照したいときはshow
コマンドで参照することができます。
SHOW PROCEDURE test_sp1
また、プロシージャを削除したいときはdrop
コマンドで削除できます。
削除するときはプロシージャ名と引数なども指定する必要があります。
DROP PROCEDURE test_sp1() DROP PROCEDURE test_sp2(f1 int, f2 varchar(20))
まとめ
毎回同じSQLを実行するようなときに、あらかじめSQLを作成しておくことで簡単に実行できるようになるので便利だなと思います。
自分もよく使うSQLなどプロシージャとして作成して効率よく作業できるようにしていこうと思います!